<!--
 * @Author: licongwei
 * @Date: 2022-03-08 15:22:29
 * @FileDescription: 地图
-->
<template>
  <div class="c-map">
    <h3 class="title">
      <p class="label">{{ totalState.name }}</p>
      <p class="number">
        <!-- :number="totalState.value" -->
        <number-scroll
          :number="totalState.value"
          :color="'#11ffe8'"
          :fontSize="24"
        ></number-scroll>
        <span class="unit">个</span>
      </p>
    </h3>
    <map-menu :state="menuState"></map-menu>
    <charts :params="mapState.params"></charts>
    <charts class="bar-chart" :params="barState.params"></charts>
  </div>
</template>
<script lang="ts">
import qhCodeSwitch from '@/utils/qhCode'
import {
  defineComponent,
  onBeforeUnmount,
  reactive,
  ref,
  computed,
  watch
} from 'vue'
import { useStore } from 'vuex'
import httpRequest from '@/service'
import { gradientColor } from '@/charts/utils'
import mapMenu from '@/components/mapMenu/mapMenu.vue'
import numberScroll from '@/components/numberScroll/numberScroll.vue'
import { ElMessage } from 'element-plus'
interface IMenuData {
  name: string
  id: string
}
interface IMenuState {
  data: IMenuData[]
  id: string
  getData: () => void
  handleClick: (id: string) => void
}
interface ITotalState {
  name: string
  value: number
  getData: () => void
}
interface IChartState {
  params: any
  getData: (data?: any) => void
}
interface IChartDataItem {
  name: string
  value: number
  adcode: string
  unit: string
  list: IData[]
  selected?: boolean
}
interface IData {
  name: string
  value: number
}
export default defineComponent({
  name: 'cMap',
  props: {
    type: {
      type: String,
      default: ''
    }
  },
  components: {
    numberScroll,
    mapMenu
  },
  emit: ['change'],
  setup(props, { emit }) {
    const adcode = ref('650000')
    // const adcode = ref('650000')
    let message: any = null
    // 切换菜单
    const menuState: IMenuState = reactive({
      data: [],
      id: '',
      getData: () => {
        httpRequest
          .get({ url: 'M1MapMenu' })
          .then((res) => {
            menuState.data = res.data
            menuState.id = menuState.data[0].id
            mapState.getData()
          })
          .catch(() => {
            console.log('请求失败')
          })
      },
      handleClick: (id: string) => {
        if (menuState.id === id) return
        if (id) {
          menuState.id = id
          mapState.getData()
        } else {
          message && message.close()
          message = ElMessage.warning({
            message: '功能正在建设中。。。'
          })
        }
      }
    })

    // 监测点总数
    const totalState: ITotalState = reactive({
      name: '',
      value: 0,
      getData: () => {
        httpRequest
          .get({ url: 'M1JcdTotal' })
          .then((res) => {
            totalState.name = res.data.name
            totalState.value = res.data.value
          })
          .catch(() => {
            console.log('请求失败')
          })
      }
    })
    totalState.getData()

    // 地图
    const mapState: IChartState = reactive({
      params: {
        loading: true,
        chartInstance: null,
        forceRedraw: true,
        map: {
          value: '数量'
        },
        adcode: '650000',
        options: {
          dataset: {
            dimensions: [],
            source: []
          },
          dataZoom: {
            disabled: true
          },
          xAxis: {
            disabled: true
          },
          yAxis: {
            disabled: true
          },
          visualMap: [
            {
              type: 'piecewise',
              pieces: [],
              show: true,
              right: 50,
              bottom: 200,
              align: 'left',
              orient: 'vertical',
              itemWidth: 30,
              itemHeight: 15,
              showLabel: true,
              itemGap: 5,
              textStyle: {
                color: '#fff',
                fontSize: 16
              },
              outOfRange: {
                color: '#def1ff'
              }
            }
          ],
          legend: {
            show: false
          },
          tooltip: {
            show: true,
            axisPointer: {
              type: 'shadow',
              snap: true
            },
            confine: true,
            backgroundColor: '#1959a7',
            borderColor: '#4beeff',
            borderWidth: 1,
            padding: 12,
            textStyle: {
              color: '#fff',
              fontSize: 14
            },
            trigger: 'item',
            formatter: (params: any) => {
              if (params.data) {
                let listTemp = ''
                for (let item of params.data.list) {
                  listTemp += `<li style="line-height:26px;display: block;">
                          <span style="display: inline-block;width: 50%;text-align:left;font-size:16px;color:#e8effb;">${item.name} :</span>
                          <span style="display: inline-block;width: 50%;text-align:right;font-size:16px;font-family: 'AliHYAiHei';color:#00ffea;">${item.value}</span>
                        </li>`
                }
                return `
                    <div style="width:200px;">
                      <div style="display: flex;justify-content: space-between;">
                        <p style="color: #ffc77a;font-size:22px;line-height:40px;font-family: 'AliHYAiHei'">${
                          params.name
                        }</p>
                      </div>
                      <ul>${params.data.isHide ? '' : listTemp}</ul>
                    </div>`
              }
            }
          },
          geo: [
            {
              map: '650000',
              roam: false,
              top: '11%',
              left: '10%',
              aspectScale: 0.85,
              zoom: 1.18,
              selectedMode: true,
              label: {
                show: true,
                color: '#fff',
                fontSize: 18,
                fontFamily: 'AliHYAiHei',
                formatter: (params: any) => {
                  let result = ''
                  let itemdata = mapState.params.options.series[0].data.filter(
                    (item: any) => {
                      return item.name === params.name
                    }
                  )[0]
                  let value = itemdata ? itemdata.value : 0
                  result = `{name|${params.name}}\n{value|${
                    value === 0 ? '' : value
                  }}`
                  return result
                },
                rich: {
                  name: {
                    fontSize: 18,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 10,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 5
                  },
                  value: {
                    fontSize: 20,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    color: '#ffc22f',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 5,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 0
                  }
                }
              },
              itemStyle: {
                areaColor: '#17adbc',
                borderColor: '#fff',
                borderWidth: 2,
                shadowColor: 'rgba(0,0,0,0.6)',
                shadowBlur: 10,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              },
              emphasis: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              select: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              z: 3
            }
          ],
          series: [
            {
              type: 'map',
              map: '650000',
              geoIndex: 0,
              aspectScale: 0.85,
              data: []
            },
            {
              type: 'map',
              map: '650000',
              aspectScale: 0.85,
              zoom: 1.18,
              top: '12.7%',
              left: '10.7%',
              silent: true,
              itemStyle: {
                areaColor: '#064c8c',
                borderColor: 'rgba(255,255,255,0.5)',
                borderWidth: 1,
                shadowColor: 'rgba(0,0,0,1)',
                shadowBlur: 20,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              }
            }
          ]
        },
        event: {
          click: (params: any) => {
            // 清除默认选中
            mapState.params.options.series[0].data.forEach((item: any) => {
              if (adcode.value === item.adcode) {
                mapState.params.chartInstance.dispatchAction({
                  type: 'unselect',
                  seriesIndex: 0,
                  name: item.name
                })
              }
            })
            adcode.value =
              adcode.value === params.data.adcode
                ? '650000'
                : params.data.adcode
            emit('change', adcode.value)
            barState.params.loading = true
            setTimeout(() => {
              barState.params.loading = false
            }, 0)
          },
          customEvent: (chartInstance: any) => {
            // 保存下echarts实例
            mapState.params.chartInstance = chartInstance
            setTimeout(() => {
              // 添加默认选中
              mapState.params.options.series[0].data.forEach((item: any) => {
                if (adcode.value === item.adcode) {
                  mapState.params.chartInstance.dispatchAction({
                    type: 'select',
                    seriesIndex: 0,
                    name: item.name
                  })
                }
              })
              emit('change', adcode.value)
              barState.getData(mapState.params.options.series[0].data)
            }, 0)
          }
        },
        custom: true
      },
      getData: () => {
        mapState.params.loading = true
        httpRequest
          .get({ url: 'M1Map', params: { menuId: menuState.id } })
          .then((res) => {
            if (res.code === 200) {
              mapState.params.options.series[0].data = res.data
              if (res.pieces.length === 1 && !res.pieces[0].max) {
                const pie = { ...res.pieces[0], max: '10' }
                mapState.params.options.visualMap[0].pieces = [pie]
              } else {
                mapState.params.options.visualMap[0].pieces = res.pieces
              }
            } else {
              mapState.params.options.visualMap[0].pieces = [
                { color: '#18bed8', max: 10, min: 0 }
              ]
              mapState.params.options.series[0].data =
                mapState.params.options.series[0].data.map((i: any) => {
                  i.value = 0
                  i.isHide = true
                  return i
                })
            }
            mapState.params.loading = false
          })
          .catch(() => {
            console.log('请求失败')
          })
      }
    })

    // 柱图
    const barState: IChartState = reactive({
      params: {
        loading: true,
        map: {
          value: '数量'
        },
        options: {
          dataset: {
            dimensions: ['name', 'value'],
            source: []
          },
          legend: {
            show: false
          },
          grid: {
            top: '10px',
            left: '50px',
            right: '50px'
          },
          xAxis: [
            {
              axisLabel: {
                interval: 0,
                fontSize: '13px',
                formatter: function (value: any) {
                  if (value.includes('地区')) {
                    const dqIndex = value.indexOf('地区')
                    return value.slice(0, dqIndex) + '\n' + value.slice(dqIndex)
                  } else if (value.length <= 3) {
                    return value
                  } else {
                    return value.slice(0, 3) + '\n' + value.slice(3)
                  }
                }
              }
            }
          ],
          series: [
            {
              type: 'bar',
              itemStyle: {
                color: (item: any) => {
                  if (item.data.adcode === adcode.value) {
                    return gradientColor(['#efde1f', '#ea690a'])
                  } else {
                    return gradientColor(['#40c4ff', '#0d66ff'])
                  }
                }
              },
              label: {
                color: '#efdd1f',
                position: 'top',
                formatter: (item: any) => {
                  if (item.data.adcode === adcode.value) {
                    return item.data.value
                  } else {
                    return ''
                  }
                }
              },
              barWidth: 15
            }
          ]
        }
      },
      getData: (data: IChartDataItem[]) => {
        barState.params.loading = true

        // barState.params.options.dataset.source = qhCodeSwitch(
        //   data.sort((a: IChartDataItem, b: IChartDataItem) => {
        //     return b.value - a.value
        //   }),
        //   'adcode',
        //   'name'
        // )
        barState.params.options.dataset.source = data.sort(
          (a: IChartDataItem, b: IChartDataItem) => {
            return b.value - a.value
          }
        )
        setTimeout(() => {
          barState.params.loading = false
        }, 0)
      }
    })
    onBeforeUnmount(() => {
      message && message.close()
    })
    const refreshData = () => {
      totalState.getData()
    }
    return {
      menuState,
      totalState,
      mapState,
      barState,
      refreshData
    }
  }
})
</script>
<style lang="less" scoped>
.c-map {
  position: relative;
  height: 100%;
  .title {
    position: absolute;
    top: 0;
    left: 50px;
    z-index: 99;
    text-align: center;
    background-color: rgba(0, 71, 157, 0.3);
    border-radius: 10px;
    border: 1px solid #045092;
    padding: 20px 25px;
    .label {
      line-height: 50px;
      font-size: 20px;
      color: #ffea00;
    }
    .number {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      .unit {
        font-size: 24px;
        color: #11ffe8;
        font-family: 'AliHYAiHei';
      }
    }
    // .total {
    //   font-size: 24px;
    //   color: #11ffe8;
    //   font-family: 'AliHYAiHei';
    // }
  }
  .bar-chart {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 20%;
  }
}
</style>
